package org.millioncall.yueyoga.admin.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;

import org.apache.commons.lang.StringUtils;
import org.millioncall.openplatform.common.PaginatedList;
import org.millioncall.openplatform.util.EncryptUtils;
import org.millioncall.yueyoga.admin.dao.AuthorityDAO;
import org.millioncall.yueyoga.admin.dao.GroupDAO;
import org.millioncall.yueyoga.admin.dao.ResourceDAO;
import org.millioncall.yueyoga.admin.dao.RoleDAO;
import org.millioncall.yueyoga.admin.dao.SiteDAO;
import org.millioncall.yueyoga.admin.dao.UserDAO;
import org.millioncall.yueyoga.admin.dao.UserDetailDAO;
import org.millioncall.yueyoga.admin.model.Authority;
import org.millioncall.yueyoga.admin.model.Group;
import org.millioncall.yueyoga.admin.model.Hall;
import org.millioncall.yueyoga.admin.model.LoginUser;
import org.millioncall.yueyoga.admin.model.GroupUserModel;
import org.millioncall.yueyoga.admin.model.Resource;
import org.millioncall.yueyoga.admin.model.Role;
import org.millioncall.yueyoga.admin.model.Site;
import org.millioncall.yueyoga.admin.model.User;
import org.millioncall.yueyoga.admin.model.UserDetail;
import org.millioncall.yueyoga.admin.model.UserHallModel;
import org.millioncall.yueyoga.admin.model.UserHallRole;
import org.millioncall.yueyoga.admin.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
	private static final Logger logger = LoggerFactory
			.getLogger(UserService.class);
	private UserDAO userDAO;
	private UserDetailDAO userDetailDAO;
	private GroupDAO groupDAO;
	private RoleDAO roleDAO;
	private AuthorityDAO authorityDAO;
	private ResourceDAO resourceDAO;
	private SiteDAO siteDAO;

	public UserDAO getUserDAO() {
		return userDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	public RoleDAO getRoleDAO() {
		return roleDAO;
	}

	public void setRoleDAO(RoleDAO roleDAO) {
		this.roleDAO = roleDAO;
	}

	public AuthorityDAO getAuthorityDAO() {
		return authorityDAO;
	}

	public void setAuthorityDAO(AuthorityDAO authorityDAO) {
		this.authorityDAO = authorityDAO;
	}

	public ResourceDAO getResourceDAO() {
		return resourceDAO;
	}

	public void setResourceDAO(ResourceDAO resourceDAO) {
		this.resourceDAO = resourceDAO;
	}

	public SiteDAO getSiteDAO() {
		return siteDAO;
	}

	public void setSiteDAO(SiteDAO siteDAO) {
		this.siteDAO = siteDAO;
	}

	@Override
	public boolean updatePassword(Map<String, Object> map) {
		int i = userDAO.updatePassword(map);
		if (i > 0) {
			return true;
		} else {
			return false;
		}
	}

	// 对登录信息的有效性验证
	public LoginResult userLogin(LoginUser user, String sessionCaptcha) {
		LoginResult lr = new LoginResult();
		String username = user.getUsername();
		if (StringUtils.isBlank(username)) {
			lr.setResultMsg("用户名不可为空");
			return lr;
		}
		if (username.length() < 3 || username.length() > 15) {
			lr.setResultMsg("用户名长度必须介于3-15之间");
			return lr;
		}
		String password = user.getPassword();
		if (StringUtils.isBlank(password)) {
			lr.setResultMsg("密码不可为空");
			return lr;
		}
		if (password.length() < 6 || password.length() > 15) {
			lr.setResultMsg("密码长度必须介于6-15之间");
			return lr;
		}

		final User dbuser = getAuthenticateUserByUsername(user.getUsername());// 从数据库中取出用户对象
		if (dbuser == null) {
			lr.setResultMsg("您输入的用户名不存在");
			return lr;
		}
		if (!dbuser.isEnabled()) {
			lr.setResultMsg("您输入的用户名未启用");
			return lr;
		}
		if (dbuser.isLocked()) {
			lr.setResultMsg("该用户已被锁定");
			return lr;
		}
		if (dbuser.isUsernameExpired()) {
			lr.setResultMsg("您的用户名已过期");
			return lr;
		}
		if (dbuser.isAuthorityExpired()) {
			lr.setResultMsg("您的用户权限已过期");
			return lr;
		}

		// 分馆判断
		if (!dbuser.getOrganizationId().equals(user.getOrganization())) {
			lr.setResultMsg("选择的分馆下无此用户");
			return lr;
		}

		if (dbuser.getGroupName().equals("users")) {
			lr.setResultMsg("该用户没有权限登录");
			return lr;
		}
		List<UserHallRole> rolesList = this.findRoleId(user.getUsername());
		UserHallRole rol = null;
		for (int i = 0; i < rolesList.size(); i++) {
			rol = rolesList.get(i);
			if (rol.getRoleId() == null) {
				lr.setResultMsg("没有给" + rol.getGroupName() + "组指定资源");
				return lr;
			}
		}

		if (!EncryptUtils.encryptTextInMD5(
				user.getPassword() + "{" + user.getUsername() + "}").equals(
				dbuser.getPassword())) {// 如果密码不相同
			Site site = this.siteDAO.getSite();

			if (site.isEnableWrongPwdLimit()) {// 如果启用了密码错误次数检查
				int allowTimes = site.getAllowWrongPwdTimes();// 允许密码错误的次数
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				Date today = null;
				try {
					today = sdf.parse(sdf.format(new Date()));
				} catch (ParseException e) {
					logger.error("日期解析异常", e);
				}
				int remainTimes = allowTimes - dbuser.getPwdWrongTimes() - 1;
				Date lastWrongTime = dbuser.getLastPwdWrongTime();

				if (lastWrongTime != null
						&& lastWrongTime.compareTo(today) == 0) {
					if (remainTimes == 0) {
						lr.setResultMsg("您剩余输入密码的次数为0，你的用户已被锁定");
						dbuser.setLocked(true);
					} else {
						lr.setResultMsg("您剩余输入密码的次数为" + remainTimes);
						dbuser.setPwdWrongTimes(dbuser.getPwdWrongTimes() + 1);
					}
				} else {
					lr.setResultMsg("您剩余输入密码的次数为" + (allowTimes - 1));
					dbuser.setLastPwdWrongTime(today);
					dbuser.setPwdWrongTimes(1);
				}
				// 异步进行更新登录的用户信息
				Executors.newSingleThreadExecutor().submit(new Runnable() {
					@Override
					public void run() {
						updateUser(dbuser);
					}
				});
				return lr;
			} else {
				lr.setResultMsg("您输入的密码不正确，请重新输入");
				return lr;
			}
		}
		lr.setSuccess(true);
		lr.setResultMsg("成功通过验证");
		dbuser.setLoginTimes(dbuser.getLoginTimes() + 1);// 修改用户登录次数，自增1
		dbuser.setLastLoginTime(user.getLoginTime());// 设置登录时间
		dbuser.setLastLoginIp(user.getLoginIp());// 设置登录ip

		// 异步进行更新登录的用户信息
		Executors.newSingleThreadExecutor().submit(new Runnable() {
			@Override
			public void run() {
				updateUser(dbuser);
			}
		});
		lr.setUser(dbuser);
		return lr;
	}

	// 根据用户名取得认证用户
	public User getAuthenticateUserByUsername(String username) {
		User user = null;
		if (StringUtils.isNotBlank(username)) {
			user = userDAO.findByUsername(username);

			if (user != null) {
				List<Group> groups = groupDAO.findByUserId(user.getId());
				if (groups != null && !groups.isEmpty()) {
					for (Group group : groups) {
						List<Role> roles = roleDAO.findRolesByGroupId(group
								.getId());
						if (roles != null && !roles.isEmpty()) {
							for (Role role : roles) {
								List<Authority> authorities = authorityDAO
										.findAuthoritiesByRoleId(role.getId());
								if (authorities != null
										&& !authorities.isEmpty()) {
									for (Authority authority : authorities) {
										List<Resource> resources = resourceDAO
												.findResourceByAuthorityId(authority
														.getId());
										authority.setResources(resources);
									}
								}
								role.setAuthorities(authorities);
							}
						}
						group.setRoles(roles);
					}

					user.setGroups(groups);
				}
			}
		}
		return user;
	}

	// 根据编号取得用户
	public User getUserById(String id) {
		return userDAO.findById(id);
	}

	// 根据用户名取得用户
	public User getUserByUsername(String username) {
		if (StringUtils.isNotBlank(username)) {
			return userDAO.findByUsername(username);
		}
		return null;
	}

	// 根据用户邮箱取得用户
	public User getUserByEmail(String email) {
		List<User> dbusers = userDAO.findByProperty("email", email);
		return dbusers.size() > 0 ? dbusers.get(0) : null;
	}

	// 取得指定页面的用户
	public PaginatedList<User> getUsersInPage(int start, int limit,
			Map<String, Object> map) {
		return userDAO.findUsersInPage(start, limit, map);
	}

	public static class LoginResult {
		private boolean isSuccess = false;// 是否成功登录
		private String resultMsg;// 结果信息
		private User user;// 登录后的用户，只在登录成功时，才有值

		public boolean isSuccess() {
			return isSuccess;
		}

		public void setSuccess(boolean isSuccess) {
			this.isSuccess = isSuccess;
		}

		public String getResultMsg() {
			return resultMsg;
		}

		public void setResultMsg(String resultMsg) {
			this.resultMsg = resultMsg;
		}

		public User getUser() {
			return user;
		}

		public void setUser(User user) {
			this.user = user;
		}
	}

	// 取得多个用户组的中文名
	public String getCnStrGroups(List<Group> groups) {
		if (groups.isEmpty()) {
			return null;
		}
		String rtn = "";
		for (Group group : groups) {
			rtn += group.getNamecn() + ",";
		}
		return rtn.substring(0, rtn.length() - 1);
	}

	// 删除用户
	@Override
	public int deleteUserById(List<String> Ids) {
		return this.userDAO.deleteUserById(Ids);
	}

	// 添加用户
	public boolean saveUser(User user) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (user == null) {
			return false;
		}
		String id = UUID.randomUUID().toString().replace("-", "");
		map.put("id", id);
		map.put("username", user.getUsername());
		map.put("password", user.getPassword());
		map.put("email", user.getEmail());
		map.put("expireTime", user.getExpireTime());
		map.put("createTime", user.getCreateTime());
		map.put("enabled", 1);
		map.put("status", 1);
		map.put("locked", 0);
		map.put("loginTimes", 0);
		map.put("pwdWrongTimes", 0);
		map.put("organizationid", user.getOrganizationId());
		map.put("groups", user.getGroupId());
		if (this.userDAO.save(map) > 0) {
			map.clear();
			UserDetail ud = user.getUserDetail();
			map.put("id", id);
			if (ud != null) {
				map.put("name", ud.getName());
				map.put("phone", ud.getPhone());
				map.put("sex", ud.getSex());
				map.put("home_address", ud.getHomeAddress());
				map.put("birthday", ud.getBirthday());
				map.put("prestige", 0);
				map.put("credit", 0);
			}
			if (this.userDetailDAO.saveUserDetail(map) > 0) {
				// 默认的用户组user
				map.clear();
				map.put("uid", id);
				map.put("gid", 1);
				map.put("enabled", 1);
				return userDAO.saveUserGroup(map) > 0;
			}
		}
		return false;
	}

	// 修改用户所属组
	@Override
	public boolean updateUserGroups(User dbuser) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", dbuser.getId());
		map.put("groups", dbuser.getGroupName());
		if (userDAO.updateUserGroups(map) > 0) {
			return true;
		} else {
			return false;
		}
	}

	// 修改用户
	public boolean updateUser(User user) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (user != null) {
			if (StringUtils.isNotBlank(user.getUsername())) {
				map.put("username", user.getUsername());
			}
			if (StringUtils.isNotBlank(user.getPassword())) {
				map.put("password", user.getPassword());
			}
			if (StringUtils.isNotBlank(user.getEmail())) {
				map.put("email", user.getEmail());
			}

			map.put("enabled", user.isEnabled());
			map.put("status", user.getStatus());
			map.put("locked", user.isLocked());
			map.put("createtime", user.getCreateTime());
			map.put("logintimes", user.getLoginTimes());
			map.put("pwdwrongtimes", user.getPwdWrongTimes());
			map.put("organizationId", user.getOrganizationId());

			if (StringUtils.isNotBlank(user.getGroupName())) {
				map.put("groups", user.getGroupName());
			}
			if (user.getExpireTime() != null) {
				map.put("expiretime", user.getExpireTime());
			}
			if (StringUtils.isNotBlank(user.getId())) {
				map.put("id", user.getId());
			} else {
				return false;
			}
			if (this.userDAO.updateUser(map) > 0) {
				map.clear();
				map.put("id", user.getId());
				UserDetail ud = user.getUserDetail();
				if (ud != null) {
					if (StringUtils.isNotBlank(ud.getName())) {
						map.put("username", ud.getName());
					}
					if (StringUtils.isNotBlank(ud.getPhone())) {
						map.put("userPhone", ud.getPhone());
					}
					if (StringUtils.isNotBlank(ud.getSex())) {
						map.put("sex", ud.getSex());
					}
					if (StringUtils.isNotBlank(ud.getHomeAddress())) {
						map.put("homeAddress", ud.getHomeAddress());
					}
					if (ud.getBirthday() != null) {
						map.put("birthday", ud.getBirthday());
					}
					if (this.userDetailDAO.updateUserDetail(map) > 0) {
						return true;
					}
				}
			}
		}
		return false;
	}

	// 批量删除用户
	public int deleteUsersByIds(String[] ids) {
		if (ids == null || ids.length == 0) {
			logger.error("未提交要删除用户的编号");
			throw new RuntimeException(" 未提交要删除用户的编号");
		} else {
			return this.userDAO.deleteByIds(ids);
		}
	}

	public boolean isGroupEnabled(String groupname) {
		List<Group> groups = this.groupDAO.findByName(groupname);
		if (groups != null && groups.size() > 0) {
			return groups.get(0).isGroupEnabled();
		} else {
			throw new RuntimeException("用户组名称不存在 ");
		}
	}

	public UserDAO getUserDao() {
		return userDAO;
	}

	public void setUserDao(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	public GroupDAO getGroupDAO() {
		return groupDAO;
	}

	public void setGroupDAO(GroupDAO groupDAO) {
		this.groupDAO = groupDAO;
	}

	@Override
	public List<User> findAllUsers(Map<String, Object> map) {
		return this.userDAO.findAllUsers(map);
	}

	@Override
	public User findById(String Id) {
		return this.userDAO.findById(Id);
	}

	@Override
	public boolean updateUser(Map<String, Object> map) {
		int i = userDAO.updateUser(map);
		if (i > 0) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public PaginatedList<User> findByGroupInPage(Integer start, Integer limit,
			String name) {
		return this.userDAO.findByGroupInPage(start, limit, name);
	}

	@Override
	public int deleteByGroup(String name) {
		return this.userDAO.deleteByGroup(name);
	}

	@Override
	public List<User> findByGroup(Integer start, Integer limit, String name) {
		return this.userDAO.findByGroup(start, limit, name);
	}

	@Override
	public List<User> findAllAssignedTo(String name) {
		return this.userDAO.findAllAssignedTo(name);
	}

	@Override
	public List<User> findByProperty(String key, String value) {
		if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
			return this.userDAO.findByProperty(key, value);
		}
		return null;
	}

	public UserDetailDAO getUserDetailDAO() {
		return userDetailDAO;
	}

	public void setUserDetailDAO(UserDetailDAO userDetailDAO) {
		this.userDetailDAO = userDetailDAO;
	}

	public List<User> findTaskUser() {
		return this.userDAO.findTaskUser();
	}

	@Override
	public List<GroupUserModel> findUsersByGroupId(String groupId,
			String organizationId) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (StringUtils.isNotBlank(groupId)
				&& StringUtils.isNotBlank(organizationId)) {
			map.put("groupId", groupId);
			map.put("organizationId", organizationId);
			return this.userDAO.findGroupUserByGroupId(map);
		}
		return null;
	}

	@Override
	public List<UserHallModel> findUserGroupHall(Map<String, Object> map) {
		return userDAO.findUserGroupHall(map);
	}

	@Override
	public Hall findUserByHallName(String hallcode) {
		return this.userDAO.findUserByHallName(hallcode);
	}

	@Override
	public List<UserHallRole> findRoleId(String userId) {
		return userDAO.findRoleId(userId);
	}

}
